home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1996 #15
/
Monster Media Number 15 (Monster Media)(July 1996).ISO
/
prog_c
/
cuj0696.zip
/
DWYER.ZIP
/
QFLOAT
/
QPOW.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-02-25
|
2KB
|
155 lines
/* qpow.c */
/* power function: z = x**y */
#include "qhead.h"
#include "mconf.h"
extern QELT qone[];
int qpowi(), mtherr();
int qpow( x, y, z )
QELT *x, *y, *z;
{
QELT w[NQ];
long li;
qfloor( y, w );
if( qcmp(y,w) == 0 )
{
qifrac( y, &li, w );
if( li < 0 )
li = -li;
if( li < 16384L ) /* 02-20-96 per Steve Moshier */
{
qpowi( x, y, z );
return 0;
}
}
/* z = exp( y * log(x) ) */
qlog( x, w );
qmul( y, w, w );
qexp( w, z );
return 0;
}
/* y is integer valued. */
int qpowi( x, y, z )
QELT x[], y[], z[];
{
QELT w[NQ];
long li, lx;
int signx, signy;
qifrac( y, &li, w );
if( li < 0 )
lx = -li;
else
lx = li;
if( lx == 0x7fffffff )
{
qpow( x, y, z );
return 0;
}
if( x[1] == 0 )
{
if( li == 0 )
{
qmov( qone, z );
return 0;
}
else if( li < 0 )
{
qinfin( z );
return 0;
}
else
{
qclear( z );
return 0;
}
}
if( li == 0L )
{
qmov( qone, z );
return 0;
}
qmov( x, w );
signx = w[0];
w[0] = 0;
if( li < 0 )
{
li = -li;
signy = -1;
}
else
signy = 0;
/* First bit of the power */
if( li & 1 )
{
qmov( w, z );
}
else
{
qmov( qone, z );
signx = 0;
}
/* Overflow detection */
/*
lx = signy * li * (long)w[1];
if( lx > (long)MAXEXP )
{
qinfin( z );
mtherr( "qpowi", OVERFLOW );
goto done;
}
if( lx <= 0 )
{
qclear( z );
return 0;
}
*/
li >>= 1;
while( li != 0L )
{
qmul( w, w, w ); /* arg to the 2-to-the-kth power */
if( li & 1L ) /* if that bit is set, then include in product */
qmul( w, z, z );
li >>= 1;
}
/*
done:
*/
if( signx )
qneg( z ); /* odd power of negative number */
if( signy )
{
if( z[1] != 0 )
{
qdiv( z, qone, z );
}
else
{
qinfin( z );
mtherr( "qpowi", OVERFLOW );
}
}
return 0;
}